import requests
import json
import time
import datetime
import urllib.parse
from typing import List, Tuple, Optional, Dict, Any, Union
from requests.auth import HTTPBasicAuth

# Gerrit API配置
GERRIT_URL = "http://gerrit.gxatek.com:18080"
USERNAME = "fxxian"
PASSWORD = "KXZTcJJNwZ6yvBVeUzg2hGmUwRTHd2CHM47t2ten0w"

def read_repos_from_file(file_path: str) -> List[str]:
    """从文件中读取仓库列表"""
    with open(file_path, "r") as file:
        repos = [line.strip() for line in file.readlines() if line.strip()]
    return repos

def create_branch_from_ref(repo: str, branch: str, base_ref: str, auth: HTTPBasicAuth) -> Tuple[bool, Optional[str]]:
    """从现有引用创建新分支"""
    print(f"正在基于 {base_ref} 为项目 {repo} 创建分支 {branch}")
    
    # 对仓库名称和分支名进行URL编码
    encoded_repo = urllib.parse.quote(repo, safe='')
    encoded_branch = urllib.parse.quote(branch, safe='')
    url = f"{GERRIT_URL}/a/projects/{encoded_repo}/branches/{encoded_branch}"
    
    try:
        # 直接使用引用名作为revision创建分支
        data = {
            "revision": base_ref
        }
        
        response = requests.put(
            url,
            auth=auth,
            headers={"Content-Type": "application/json"},
            data=json.dumps(data)
        )
        
        if response.status_code in [201, 200]:
            print(f"项目 {repo} 的 {branch} 分支创建成功")
            return True, None
        else:
            error_msg = f"项目 {repo} 的 {branch} 分支创建失败: {response.status_code}, {response.text}"
            print(error_msg)
            return False, error_msg
    
    except Exception as e:
        error_msg = f"创建项目 {repo} 的 {branch} 分支时发生错误: {str(e)}"
        print(error_msg)
        return False, error_msg

def save_failed_branches(failed_branches: List[Tuple[str, str, str]], filename: str) -> str:
    """将创建失败的分支信息记录到文件中"""
    timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
    output_file = f"{filename}_{timestamp}_failed.txt"
    
    with open(output_file, "w") as file:
        file.write(f"创建失败的分支列表 - {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
        file.write("=" * 80 + "\n")
        
        for project, branch, error in failed_branches:
            file.write(f"\n项目: {project}\n")
            file.write(f"分支: {branch}\n")
            file.write(f"错误: {error}\n")
            file.write("-" * 50 + "\n")
    
    print(f"创建失败的分支信息已保存到文件: {output_file}")
    return output_file

def bulk_create_branches(repos_file: str, branch: str, base_ref: str = "refs/meta/config") -> Tuple[int, int]:
    """批量为仓库创建分支"""
    # 读取仓库列表
    repos = read_repos_from_file(repos_file)
    
    # 设置认证信息
    auth = HTTPBasicAuth(USERNAME, PASSWORD)
    
    # 统计信息
    success_count = 0
    failed_count = 0
    failed_branches: List[Tuple[str, str, str]] = []
    
    # 创建分支
    for repo in repos:
        success, error_msg = create_branch_from_ref(repo, branch, base_ref, auth)
            
        if success:
            success_count += 1
        else:
            failed_count += 1
            if error_msg is not None:  # This check is to satisfy type checker
                failed_branches.append((repo, branch, error_msg))
        
        # 添加延迟以避免过多请求
        time.sleep(0.5)
    
    print(f"所有分支创建完成，成功: {success_count}，失败: {failed_count}")
    
    # 如果存在创建失败的分支，将失败信息记录到文件中
    if failed_branches:
        failed_file = save_failed_branches(failed_branches, "failed_branches")
    
    return success_count, failed_count

def main():
    """主函数"""
    repos_file = "repo.txt"
    branch_name = "master"  # 要创建的分支名称
    base_ref = "refs/meta/config"
    
    print(f"将基于{base_ref}为仓库创建{branch_name}分支")
    
    result = bulk_create_branches(
        repos_file=repos_file,
        branch=branch_name,
        base_ref=base_ref
    )
    return result

if __name__ == "__main__":
    main()
